package com.util;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * 使用内省实现
 *
 * @author Cc
 * 2024-03-28
 */
public class IntrospectionBeanUtil {
    /**
     * 设置 任意对象 属性
     *
     * @param bean         任意实体
     * @param propertyName 属性名称
     * @param value        值
     */
    public static void setProperty(Object bean, String propertyName, Object value) throws IllegalAccessException, IntrospectionException, InvocationTargetException {
        PropertyDescriptor propertyDescriptor = new PropertyDescriptor(propertyName, bean.getClass());

        Method writeMethod = propertyDescriptor.getWriteMethod();

        writeMethod.invoke(bean, value);
    }

    /**
     * 获取 任意实体 属性值
     *
     * @param bean         任意实体
     * @param propertyName 属性名称
     * @return {@link Object}
     */
    public static Object getProperty(Object bean, String propertyName) throws IntrospectionException, InvocationTargetException, IllegalAccessException {
        PropertyDescriptor propertyDescriptor = new PropertyDescriptor(propertyName, bean.getClass());

        Method readMethod = propertyDescriptor.getReadMethod();

        return readMethod.invoke(bean);
    }

    public static void copyProperties(Object source, Object target) throws IllegalAccessException, IntrospectionException, InvocationTargetException {
        Class<?> sourceClass = source.getClass();
        Class<?> targetClass = target.getClass();

        if (targetClass == sourceClass) {
            BeanInfo sourceInfo = Introspector.getBeanInfo(sourceClass, Object.class);
            BeanInfo targetInfo = Introspector.getBeanInfo(targetClass, Object.class);

            PropertyDescriptor[] sourceInfoPropertyDescriptors =
                    sourceInfo.getPropertyDescriptors();
            PropertyDescriptor[] targetInfoPropertyDescriptors =
                    targetInfo.getPropertyDescriptors();

            for (int i = 0; i < sourceInfoPropertyDescriptors.length; i++) {
                Object value = sourceInfoPropertyDescriptors[i].getReadMethod().invoke(source);

                Method writeMethod = targetInfoPropertyDescriptors[i].getWriteMethod();
                writeMethod.invoke(target, value);
            }
        } else
            System.out.println("不是一个玩意");
    }
}
